---
import Layout from '~layouts/VanillaDemo.astro';
import { title } from './_textured-quads-po2image-loader.json';
---

<Layout title={title}>
  <canvas id="canvas-container" resize-to="window"></canvas>

  <div id="texture-preview" class="texture-preview"></div>
</Layout>

<style>
  body {
    height: 100vh;
    overflow-y: hidden;
  }
  body {
    background-color: #391e39;
    background: radial-gradient(circle, rgba(93, 101, 116, 1) 0%, rgba(37, 50, 98, 1) 100%);
  }
  .texture-preview {
    background-color: rgba(86, 101, 115, 80%);
    border: 5px solid #324168;
    border-radius: 5px;
    width: 150px;
    height: 150px;
    position: fixed;
    bottom: 20px;
    right: 20px;
    box-shadow: 5px 5px 10px rgba(0 0 0 / 50%);
    overflow: hidden;
  }
  .texture-preview :global(img),
  .texture-preview :global(canvas) {
    max-width: 100%;
  }
</style>

<script>
  import {PowerOf2ImageLoader, TextureCoords, VertexObjects} from '@spearwolf/twopoint5d';
  import {DoubleSide, NearestFilter, RawShaderMaterial, Texture} from 'three';
  import {InstancedQuadsGeometry} from '~demos/instanced-quads/InstancedQuadsGeometry';
  import fragmentShaderSource from '~demos/shaders/textured-quads.frag?url';
  import vertexShaderSource from '~demos/shaders/textured-quads.vert?url';
  import {PerspectiveOrbitDemo} from '~demos/utils/PerspectiveOrbitDemo';
  import assetsUrl from '~demos/utils/assetsUrl';
  import loadShaderSource from '~demos/utils/loadShaderSource';

  async function makeMesh(
    rows: number,
    columns: number,
    size: number,
    offset: number,
    texCoords: TextureCoords,
    texture: Texture,
  ) {
    const capacity = rows * columns;
    const geometry = new InstancedQuadsGeometry(capacity);

    geometry.basePool.createVO().make();

    for (let y = 0; y < rows; y++) {
      for (let x = 0; x < columns; x++) {
        const quad = geometry.instancedPool.createVO();

        quad.width = size * (0.6 + Math.random() * 0.45);
        quad.height = (quad.width * texCoords.height) / texCoords.width;

        quad.setInstancePosition([
          x * size * offset - ((columns - 1) * size * offset) / 2,
          y * size * offset - ((rows - 1) * size * offset) / 2,
          0,
        ]);

        quad.setTexCoords([texCoords.s, texCoords.t, texCoords.u, texCoords.v]);
      }
    }

    const material = new RawShaderMaterial({
      vertexShader: await loadShaderSource(vertexShaderSource),
      fragmentShader: await loadShaderSource(fragmentShaderSource),
      uniforms: {
        colorMap: {
          value: texture,
        },
      },
      transparent: true,
      side: DoubleSide,
    });

    const mesh = new VertexObjects(geometry, material);
    mesh.name = 'InstancedQuadsMesh';
    mesh.frustumCulled = false;

    return mesh;
  }

  const demo = new PerspectiveOrbitDemo(document.getElementById('canvas-container'), {antialias: false});

  const data = await new PowerOf2ImageLoader().loadAsync(assetsUrl('platform-blau.png'));

  console.log('loaded power-of-2 image', data);

  const texture = new Texture(data.imgEl);
  texture.magFilter = NearestFilter;
  texture.minFilter = NearestFilter;
  texture.flipY = false;
  texture.needsUpdate = true;

  document.getElementById('texture-preview').appendChild(data.imgEl);

  await demo.start(async () => {
    demo.scene.add(await makeMesh(16, 32, 10, 1, data.texCoords, texture));
  });

  console.log('TexturedQuadsMesh', demo.scene.children[0]);
</script>
